package interceptor

import (
	"fmt"
	"github.com/labstack/echo/v4"
	log "github.com/sirupsen/logrus"
	"strings"
	"time"
)

//日志处理
func Logger() echo.MiddlewareFunc {
	return func(next echo.HandlerFunc) echo.HandlerFunc {
		return func(c echo.Context) error {
			//开始记录数据
			req := c.Request()
			res := c.Response()
			start := time.Now()
			fields := log.Fields{
				"start_time": start,
				"remote_ip":  req.RemoteAddr,
				"host":       req.Host,
				"req_method": req.Method,
				"url":        req.URL,
				"req_header": req.Header,
				"status":     res.Status,
			}
			withFields := log.WithFields(fields)

			//记录执行的时间
			if err := next(c); err != nil {
				fields["error"] = err
				withFields.Error()
			}
			stop := time.Now()
			fields["end_time"] = stop
			withFields.Info()
			return nil
		}
	}
}

//异常回退
func Recover() echo.MiddlewareFunc {
	return func(next echo.HandlerFunc) echo.HandlerFunc {
		return func(c echo.Context) error {
			defer func() {
				if r := recover(); r != nil {
					err, ok := r.(error)
					if !ok {
						err = fmt.Errorf("%v", r)
					}
					c.Error(err)
				}
			}()
			return next(c)
		}
	}
}

// 跨域
func Cors() echo.MiddlewareFunc {
	return func(next echo.HandlerFunc) echo.HandlerFunc {
		return func(c echo.Context) error {
			origin := c.Request().Header.Get("Origin") //请求头部
			var headerKeys []string                    // 声明请求头keys
			for k, _ := range c.Request().Header {
				headerKeys = append(headerKeys, k)
			}
			headerStr := strings.Join(headerKeys, ", ")
			if headerStr != "" {
				headerStr = fmt.Sprintf("access-control-allow-origin, access-control-allow-headers, %s", headerStr)
			} else {
				headerStr = "access-control-allow-origin, access-control-allow-headers"
			}
			if origin != "" {
				c.Response().Header().Set("Access-Control-Allow-Origin", "*")
				c.Response().Header().Set("Access-Control-Allow-Origin", "*")                                       // 这是允许访问所有域
				c.Response().Header().Set("Access-Control-Allow-Methods", "POST, GET, OPTIONS, PUT, DELETE,UPDATE") //服务器支持的所有跨域请求的方法,为了避免浏览次请求的多次'预检'请求
				//  header的类型
				c.Response().Header().Set("Access-Control-Allow-Headers", "Authorization, Content-Length, X-CSRF-Token, Token,session,X_Requested_With,Accept, Origin, Host, Connection, Accept-Encoding, Accept-Language,DNT, X-CustomHeader, Keep-Alive, User-Agent, X-Requested-With, If-Modified-Since, Cache-Control, Content-Type, Pragma")
				// 允许跨域设置                                                                                                      可以返回其他子段
				c.Response().Header().Set("Access-Control-Expose-Headers", "Content-Length, Access-Control-Allow-Origin, Access-Control-Allow-Headers,Cache-Control,Content-Language,Content-Type,Expires,Last-Modified,Pragma,FooBar") // 跨域关键设置 让浏览器可以解析
				c.Response().Header().Set("Access-Control-Max-Age", "172800")                                                                                                                                                           // 缓存请求信息 单位为秒
				c.Response().Header().Set("Access-Control-Allow-Credentials", "false")                                                                                                                                                  //  跨域请求是否需要带cookie信息 默认设置为true
				c.Set("content-type", "application/json")                                                                                                                                                                               // 设置返回格式是json
			}
			return next(c) //  处理请求
		}
	}
}
